<?php
/* 
    Name：FastPHP
    CopyRight: Mr.Fu 2019SR0832915
*/
namespace app\base;
/*
    图片处理类
    Author:FastPHP
*/
use \app\base\Common;

class Image extends Common
{
    //获取图片真实信息
    static function getImageInfo($imgfile)
    {
        $imageinfo=getimagesize($imgfile);
        $types=array(1=>'gif',2=>'jpg',3=>'png',4=>'swf',5=>'psd',6=>'bmp',7=>'tiff',8=>'tiff',9=>'jpc',10=>'jp2',11=>'jpx',12=>'jb2',13=>'swc',14=>'iff',15=>'wbmp',16=>'xbm',17=>'ico',18=>'webp');
        if($imageinfo){
            list($width, $height, $type)=$imageinfo;
            if($types[$type]){
                $arr['type']=$types[$type];
                $arr['width']=$width;
                $arr['height']=$height;
                return $arr;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }
    //图片格式转换:支持源：jpg,png,gif,bmp,支持输出：jpg,png,gif,webp $src_clear 源文件是否清理
    static function convert($src,$dst='',$to_ext='jpg',$src_clear=false)
    {
        $info=self::getImageInfo($src);
        //源和目标格式相同不能转换
        if($info['type']==$to_ext){
             return $src;
        }
        switch($info['type']){
            case 'jpg':
                $img=imagecreatefromjpeg($src);
                break;
            case 'gif':
                $img=imagecreatefromgif($src);
                break;
            case 'png':
                $img=imagecreatefrompng($src);
                break;
            case 'bmp':
                $img=imagecreatefrombmp($src);
                break;
            case 'webp':
                // $img=imagecreatefromwebp($src);
                break;
            default:
            break;
        }
        if($src_clear){
            \unlink($src);
        }        
        //如果输出目录为空则组装输出路径
        if($dst==""){
            $file=pathinfo($src);
            $dst=$file['dirname'].DS.$file['filename'].'.'.$to_ext;
        }
        if($img){
            switch($to_ext){
                case 'jpg':
                    ImageJPEG($img,$dst);
                    return $dst;
                case 'png':
                    ImagePNG($img,$dst);
                    return $dst;
                case 'gif';
                    ImageGIF($img,$dst);
                    return $dst;
                case 'webp':
                    ImageWEBP($img,$dst);
                    return $dst;
                default:
                break;
            }
        }
        return false;
    }
    //生成验证图片
    static function getAuthImage($text) {
        $im_x = 160;
        $im_y = 50;
        $im = imagecreatetruecolor($im_x,$im_y);
        $text_c = ImageColorAllocate($im, mt_rand(0,100),mt_rand(0,100),mt_rand(0,100));
        $tmpC0=mt_rand(100,255);
        $tmpC1=mt_rand(100,255);
        $tmpC2=mt_rand(100,255);
        $buttum_c = ImageColorAllocate($im,$tmpC0,$tmpC1,$tmpC2);
        imagefill($im, 16, 13, $buttum_c);
        $font = APP_PATH.'/data/font/en.ttf';
        for ($i=0;$i<strlen($text);$i++){
            $tmp =substr($text,$i,1);
            $array = array(-1,1);
            $p = array_rand($array);
            $an = $array[$p]*mt_rand(1,30);//角度
            $size = 28;
            imagettftext($im, $size, $an, 15+$i*$size, 35, $text_c, $font, $tmp);
        }
        $distortion_im = imagecreatetruecolor ($im_x, $im_y);
        imagefill($distortion_im, 16, 13, $buttum_c);
        for ( $i=0; $i<$im_x; $i++) {
            for ( $j=0; $j<$im_y; $j++) {
                $rgb = imagecolorat($im, $i , $j);
                if( (int)($i+20+sin($j/$im_y*2*M_PI)*10) <= imagesx($distortion_im)&& (int)($i+20+sin($j/$im_y*2*M_PI)*10) >=0 ) {
                    imagesetpixel ($distortion_im, (int)($i+10+sin($j/$im_y*2*M_PI-M_PI*0.1)*4) , $j , $rgb);
                }
            }
        }
        //加入干扰象素;
        $count = 500;//干扰像素的数量
        for($i=0; $i<$count; $i++){
            $randcolor = ImageColorallocate($distortion_im,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));
            imagesetpixel($distortion_im, mt_rand()%$im_x , mt_rand()%$im_y , $randcolor);
        }
        $rand = mt_rand(5,30);
        $rand1 = mt_rand(15,25);
        $rand2 = mt_rand(5,10);
        for ($yy=$rand; $yy<=+$rand+2; $yy++){
            for ($px=-80;$px<=80;$px=$px+0.1){
                $x=$px/$rand1;
                if ($x!=0){
                    $y=sin($x);
                }
                $py=$y*$rand2;
                imagesetpixel($distortion_im, $px+80, $py+$yy, $text_c);
            }
        }
        ob_clean();      
        ImagePNG($distortion_im);//以PNG格式将图像输出到浏览器或文件;
        ImageDestroy($distortion_im);//销毁一图像,释放与image关联的内存;
        ImageDestroy($im);
        echo ob_get_clean();
    }
    //保存base64的图片数据
    static function SaveBase64Img($data){
        $dir		= DS.'uploads'.DS.'images'.DS.date('Ymd',time()).DS;
        $savepath 	= ROOT_PATH.$dir;
        if(!file_exists($savepath)){
            mkdir($savepath);
        }
        $filename 	= time().GetRandStr(10).'.jpg';		
        $data 		= substr($data,22);
        $tmp  		= base64_decode($data);
        file_put_contents($savepath.DS.$filename,$tmp);
        return $dir.$filename;
    }
    /*
        模糊化像素颜色，按照四舍五入的方式
    */
    static function Probably($int){
        $len=strlen($int);
        if($len==1){
            return 0;
        }elseif($len==2 or $len==3){
            return round($int/10)."0";
        }else{
            return false;
        }
    }
    /*
        模糊化像素颜色，按照30的步长模糊，把255*255*255种颜色，模糊化:9*9*9的方式
    */
    static function Probably2($int){
        $ints=array(
            0=>array(0,29),
            30=>array(30,59),
            60=>array(60,89),
            90=>array(90,119),
            120=>array(120,149),
            150=>array(150,179),
            180=>array(180,209),
            210=>array(210,239),
            240=>array(240,256),
        );
        foreach($ints as $k=>$v){
            $min=$v[0];
            $max=$v[1];
            if(($int>=$min)and($int<=$max)){
                return $k;
            }
        }
    }
    /*
        获得指定图片的颜色列表
    */
    static function GetImgColorList($src_file,$samples=50,$top=20){
        //图片的等比缩放 因为PHP只能对资源进行操作，所以要对需要进行缩放的图片进行拷贝，创建为新的资源
        $src=imagecreatefromjpeg($src_file);
        //取得源图片的宽度和高度
        $size_src=getimagesize($src_file);
        $w=$size_src['0'];
        $h=$size_src['1'];
        $max=$samples;
        //指定缩放出来的最大的宽度（也有可能是高度） 根据最大值为300，算出另一个边的长度，得到缩放后的图片宽度和高度
        if($w > $h){
            $w=$max;
            $h=$h*($max/$size_src['0']);
        }else{
            $h=$max;
            $w=$w*($max/$size_src['1']);
        }
        //声明一个$w宽，$h高的真彩图片资源
        $image=imagecreatetruecolor($w, $h);
        //关键函数，参数（目标资源，源，目标资源的开始坐标x,y, 源资源的开始坐标x,y,目标资源的宽高w,h,源资源的宽高w,h）
        imagecopyresampled($image, $src, 0, 0, 0, 0, $w, $h, $size_src['0'], $size_src['1']);
        //告诉浏览器以图片形式解析
        ImageJpeg($image,RUNTIME_PATH.'colorindex.jpg',100);
        $sm_img=imagecreatefromjpeg(RUNTIME_PATH."colorindex.jpg");
        $sm_img_size=getimagesize(RUNTIME_PATH."colorindex.jpg");
        //扫描每个像素放到数组，将相近的颜色合并，生成新主要颜色。
        $x_num=$sm_img_size[0];
        $y_num=$sm_img_size[1];
        $Color_list=array();
        $i=0;
        for($x=0;$x<$x_num;$x++){
            for($y=0;$y<$y_num;$y++){ 
                $Color_index=ImageColorAt($sm_img,$x,$y);
                $c_arr=ImageColorsForIndex($sm_img,$Color_index);            
                // 模糊化像素RGB值
                $r=self::Probably2($c_arr['red']);              
                $g=self::Probably2($c_arr['green']);              
                $b=self::Probably2($c_arr['blue']); 
                $color_str=$r.','.$g.','.$b;   
                $Color_list[$i]=$color_str;
                $i++;
            }
        }
        $arr=array_count_values($Color_list);
        arsort($arr);
        $step=1;
        $Color_Top=array();
        foreach($arr as $k=>$v){
            if($step<=$top){
                $Color_Top[]=$k;
                $step++;
            } 
        }
        unlink(RUNTIME_PATH.'colorindex.jpg');
        //销毁资源
        imagedestroy($image);
        imagedestroy($src);
        if(is_array($Color_Top)){
            return $Color_Top;
        }else{
            return false;
        }
    } 
    
    //图片的等比缩放 本函数的文件输出方式是选择操作,如果$out_file为空刚是覆盖式操作,支持jpg,png,gif,bmp
    static function ImageCompress($src_file,$out_file="",$max='1024',$quality='80'){ 
    	
		//获取图片信息
		$type=getimagesize($src_file)['mime'];
		//识别图片类型
		if($type=='image/jpeg'){
			$src=imagecreatefromjpeg($src_file);
		}else if($type=='image/png'){
			$src=imagecreatefrompng($src_file);
		}else if($type=='image/gif'){
            $src=imagecreatefromgif($src_file);
		}else{
			return false;
		}
        
        $size_src=getimagesize($src_file);
        $w=$size_src['0'];
        $h=$size_src['1'];
        
        if(($w>$max)or($h>$max)){
            if($w > $h){
                $w=$max;
                $h=$h*($max/$size_src['0']);
            }else{
                $h=$max;
                $w=$w*($max/$size_src['1']);
            }
        }

        $image=imagecreatetruecolor($w, $h);
        imagecopyresampled($image, $src, 0, 0, 0, 0, $w, $h, $size_src['0'], $size_src['1']);

        if($out_file==""){
            $out_file=$src_file;
        }
        
		if($type=='image/jpeg'){
			ImageJpeg($image,$out_file,$quality);
		}else if($type=='image/png'){
			imagepng($image,$out_file);
		}else if($type=='image/gif'){
			imagegif($image,$out_file);
		}
		
        //销毁资源
        imagedestroy($image);
        imagedestroy($src);
    }
    //图片加水印函数
    //$min      :图片最小尺寸打水印要求
    //$quality  :图片保存质量级别
    //$fnt      :图片水印字体
    static function watermark($img_path,$text="",$min=470,$quality=100){
        $font = PathDS(APP_PATH.'data'.DS.'font'.DS.'zh.ttf');
        $str2=$text;
        $str2_w=(strlen($text)+3)*8;

        $im=imagecreatefromjpeg($img_path);  
        $image_info=getimagesize($img_path);
        $img_w=$image_info[0];
        $img_h=$image_info[1]; 
        //创建颜色，用于文字字体的白和阴影的黑   
        $white=imagecolorallocate($im,255,255,255);
        $black1=imagecolorallocate($im,100,100,100);   
        $black2=imagecolorallocate($im,223,223,223);   
        if($img_w>=$min){
            $l2=$img_w-$str2_w;
            $t2=$img_h-15;
            imagettftext($im,18,0, $l2+1, $t2+1, $black1, $font, $str2);   
            imagettftext($im,18,0, $l2, $t2, $white, $font, $str2); 
        }elseif($img_h>=$min){
            $l2=$img_w-15;
            $t2=$str2_w;  
            imagettftext($im,18,90, $l2+1, $t2+1, $black1, $font, $str2);  
            imagettftext($im,18,90, $l2, $t2, $white, $font, $str2); 
        }else{
            return false;
        }
        //将$im输出   
        ImageJpeg($im,$img_path,$quality);   
        //销毁$im对象   
        ImageDestroy($im); 
    }    
    /*
        多行自动文字水印(自动居中，换行)
        $temp:模板图片
        $outimg:输出路径
        $title:文字内容
        $color:十六进制的颜色
        $type:左右定位类型 0：居中 1：左对齐
        $top:顶部开始位置
        $line_size:每行文字数量
        $fontsize:字体大小
        $defaultCharWidth:单个字符宽度
    */
    static function ImageAddText($temp,$outimg,$title,$color,$type,$top,$line_size,$fontsize=20,$defaultCharWidth=26)
    {
        //字体文件
        $font = PathDS(APP_PATH.'data'.DS.'font'.DS.'zh.ttf');
        $temp_info=self::getImageInfo($temp);
        //加载模板
        $Img=imagecreatefromjpeg($temp);
        //把十六进制颜色转换成RGB
        $color=self::HexToRGB($color);
        //创建一个颜色
        $black=imagecolorallocate($Img,$color[0],$color[1],$color[2]);
        //文字顶部开始位置
        $s_top=$top;
        //每行文字高度
        $line_height=50;
        //每行文字数量
        $line_size=$line_size;
        //总文字数量
        $count=mb_strlen($title);
        //计算需要多少行显示
        $line_count=ceil($count/$line_size);
        //开始循环每行打印
        for($i=1;$i<=$line_count;$i++){
            $strat = ($i - 1)*$line_size;
            //开始剪切文字
            $txt=mb_substr($title,$strat,$line_size);
            //开始判断增涨高度
            if($i==1){
                $top=$s_top;
            }else{
                $top=$s_top+($line_height*($i-1));
            }
            //计算文字宽度
            $text_w=$defaultCharWidth*(mb_strlen($txt));
            if($type==0){
                //计算中心位置
                $left=ceil(($temp_info['width'] - $text_w) / 2);
            }else{
                $left=10;
            }
            imagettftext($Img,$fontsize,0,$left,$top, $black, $font, $txt);
        }
        //将$im输出   
        ImageJpeg($Img,$outimg,80);   
        //销毁$im对象   
        ImageDestroy($Img);         
    }    
    //获得PSD元数据
    static function GetPSDInfo($filename){
        $info=array();
        $cont=file_get_contents($filename,NULL,NULL,155,17055);
        $preg_soft="#<xap:CreatorTool>([^<]*)</xap:CreatorTool>#iUs";
        $preg_soft2="#<stEvt:softwareAgent>([^<]*)</stEvt:softwareAgent>#iUs";
        $preg_colormode="#<photoshop:ColorMode>(\d*)</photoshop:ColorMode>#iUs";
        $preg_resolution="#<tiff:XResolution>(\d*)/(\d*)</tiff:XResolution>#iUs";
        $preg_pixel="#<exif:PixelXDimension>(\d*)</exif:PixelXDimension>(\s*)<exif:PixelYDimension>(\d*)</exif:PixelYDimension>#iUs";

        preg_match_all($preg_soft,$cont,$arr_soft);
        preg_match_all($preg_soft2,$cont,$arr_soft2);
        preg_match_all($preg_colormode,$cont,$arr_colormode);
        preg_match_all($preg_resolution,$cont,$arr_resolution);
        preg_match_all($preg_pixel,$cont,$arr_pixel);

        if(isset($arr_soft[1][0])){ $info['CreatorTool']=$arr_soft[1][0];}else{$info['CreatorTool']="";}
        if(isset($arr_soft2[1][0])){ $info['softwareAgent']=$arr_soft2[1][0];}else{$info['softwareAgent']="unknown";}  
        if(isset($arr_colormode[1][0])){ $colormode=$arr_colormode[1][0];}else{ $colormode="10"; }
        if((isset($arr_resolution[1][0]))and(isset($arr_resolution[2][0]))){ $info['Resolution']=($arr_resolution[1][0]/$arr_resolution[2][0])."PPI";}else{ $info['Resolution']="unknown";}
        if((isset($arr_pixel[1][0]))and(isset($arr_pixel[3][0]))){ $info['PixelX']=$arr_pixel[1][0]; $info['PixelY']=$arr_pixel[3][0];}else{ $info['PixelX']=0; $info['PixelY']=0;}
        $cm_arr=array(0=>"Bitmap",1=>"Grayscale",2=>"Indexed",3=>"RGB",4=>"CMYK",5=>"unknown",6=>"unknown",7=>"MultichannelColorMode",8=>"SingleMode",9=>"LabMode",10=>"unknown");
        $info['ColorMode']=$cm_arr[$colormode];    
        return $info;
    }  
	/**
	* a.合成图片信息 复制一张图片的矩形区域到另外一张图片的矩形区域
	* @param  [type] $bg_image  [目标图]
	* @param  [type] $sub_image [被添加图]
	* @param  [type] $add_x     [目标图x坐标位置]
	* @param  [type] $add_y     [目标图y坐标位置]
	* @param  [type] $add_w     [目标图宽度区域]
	* @param  [type] $add_h     [目标图高度区域]
	* @param  [type] $out_image [输出图路径]
	* @return [type]            [description]
	*/
	static function ImageCopyImage($bg_image,$sub_image,$add_x,$add_y,$add_w,$add_h,$out_image){
		$bg_image_c = imagecreatefromstring(file_get_contents($bg_image));
		$sub_image_c = imagecreatefromstring(file_get_contents($sub_image));
		imagecopyresampled($bg_image_c, $sub_image_c, $add_x, $add_y, 0, 0, $add_w, $add_h, imagesx($sub_image_c), imagesy($sub_image_c));
		imagejpeg($bg_image_c, $out_image, 80);
		imagedestroy($sub_image_c);
		imagedestroy($bg_image_c);
	}	
	/**
	 * 处理成圆图片,如果图片不是正方形就取最小边的圆半径,从左边开始剪切成圆形
	 * @param  string $imgpath [description]
	 * @return [type]          [description]
	 */
	static function RoundImg($imgpath) {
		$ext     = pathinfo($imgpath);
		$src_img = null;
		//组件支持检测
		if(!function_exists('mime_content_type')){
			echo '<h1 style="color:#F00;text-align:center;">FastPHP.TOP 系统错误：请安装PHP的fileinfo扩展！</h1>';
			exit();
		}
		$mime=mime_content_type($imgpath);
		switch ($mime) {
			case 'image/jpeg':
				$src_img = imagecreatefromjpeg($imgpath);
				break;
			case 'image/png':
				$src_img = imagecreatefrompng($imgpath);
				break;
		}
		$wh  = getimagesize($imgpath);
		$w   = $wh[0];
		$h   = $wh[1];
		$w   = min($w, $h);
		$h   = $w;
		$img = imagecreatetruecolor($w, $h);
		//这一句一定要有
		imagesavealpha($img, true);
		//拾取一个完全透明的颜色,最后一个参数127为全透明
		$bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
		imagefill($img, 0, 0, $bg);
		$r   = $w / 2; //圆半径
		$y_x = $r; //圆心X坐标
		$y_y = $r; //圆心Y坐标
		for ($x = 0; $x < $w; $x++) {
			for ($y = 0; $y < $h; $y++) {
				$rgbColor = imagecolorat($src_img, $x, $y);
				if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
					imagesetpixel($img, $x, $y, $rgbColor);
				}
			}
		}
		imagepng($img, $imgpath.'.png', 8);
		imagedestroy($img);		
	}
	/**
	 * 十六进制颜色值转成rgb
	 * @param  [type] $hex [description]
	 * @return [type]      [description]
	 */
	static function HexToRGB($hex) {
		$hex = str_replace("#", "", $hex);
		if (strlen($hex) == 3) {
			$r = hexdec(substr($hex, 0, 1) . substr($hex, 0, 1));
			$g = hexdec(substr($hex, 1, 1) . substr($hex, 1, 1));
			$b = hexdec(substr($hex, 2, 1) . substr($hex, 2, 1));
		} else {
			$r = hexdec(substr($hex, 0, 2));
			$g = hexdec(substr($hex, 2, 2));
			$b = hexdec(substr($hex, 4, 2));
		}
		return array($r, $g, $b);
	}
	/**
	 * rgb颜色值转十六进制
	 * @param  [type] $rgb [description]
	 * @return [type]      [description]
	 */
	static function RGBToHex($rgb) {
		$hex = "#";
		$hex .= str_pad(dechex($rgb[0]), 2, "0", STR_PAD_LEFT);
		$hex .= str_pad(dechex($rgb[1]), 2, "0", STR_PAD_LEFT);
		$hex .= str_pad(dechex($rgb[2]), 2, "0", STR_PAD_LEFT);
		return $hex;
	}   	 
}
